package com.northpool.operator.transfer.proj;

import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.common.algorithm.OperatorTestBuild;
import com.northpool.operator.common.algorithm.TestParamBuilder;
import com.northpool.operator.common.stpclient.StpClientOperatorBase;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.type.TypeEnum;
import com.northpool.stpclient.bean.BaseResponse;
import com.northpool.stpclient.modules.geoprocess.operator.IPipelineOperator;
import com.northpool.stpclient.operator.bean.DatasetBean;
import com.northpool.stpclient.operator.bean.OperatorBean;
import com.northpool.stpclient.operator.bean.ParamBean;
import com.northpool.stpclient.operator.bean.PipelineBean;

import java.io.File;
import java.util.LinkedList;
import java.util.List;


@OperatorInfo(
        ref = "ReProjOperator",
        name = "数据重投影",
        description = ""
)
public class ReProjOperator extends StpClientOperatorBase {
    String originDataSourceId;
    String originTableName;

    String targetDataSourceId;
    String targetTableName;

    String originSrid;
    String targetSrid;
    String spatialField;

    String mode;

    @InputParams({
            @InputParam(ref = "originDataSourceId", name = "来源数据源ID", desc = "来源数据源ID", type = TypeEnum.DATASOURCE),
            @InputParam(ref = "originTableName", name = "来源表名称", desc = "来源表名称", type = TypeEnum.STRING),
            @InputParam(ref = "targetDataSourceId", name = "目标数据源ID", desc = "目标数据源ID", type = TypeEnum.DATASOURCE),
            @InputParam(ref = "targetTableName", name = "目标表名称", desc = "目标表名称", type = TypeEnum.STRING),
            @InputParam(ref = "originSrid", name = "来源坐标系SRID", desc = "来源坐标系SRID,常用SRID: 4326、4490、3857等", type = TypeEnum.STRING),
            @InputParam(ref = "targetSrid", name = "目标坐标系SRID", desc = "目标坐标系SRID,常用SRID: 4326、4490、3857等", type = TypeEnum.STRING),
            @InputParam(ref = "spatialField", name = "空间字段名称", desc = "空间字段名称，如: geom", type = TypeEnum.STRING),
            @InputParam(ref = "mode", name = "传输类型", desc = "传输类型，可选值：REPLACE,APPEND", type = TypeEnum.STRING, value = "REPLACE"),
    })
    public ReProjOperator() {
    }

    public static void main(String[] args) throws Exception {
        OperatorTestBuild.execute(ReProjOperator.class,
                TestParamBuilder.aBuilder()
                        .param("originDataSourceId", "northpool_work")
                        .param("originTableName", "DLG_BOUA_CUN_2022")
                        .param("targetDataSourceId", "northpool_work")
                        .param("targetTableName", "DLG_BOUA_CUN_2022_3857")
                        .param("originSrid", "4490")
                        .param("targetSrid", "3857")
                        .param("spatialField", "Shape")
                        .param("mode", "REPLACE")
                        .build());
    }

    @Override
    public void execute(ParamTool params) throws Exception {
        originDataSourceId = params.getStr("originDataSourceId");
        originTableName = params.getStr("originTableName");
        targetDataSourceId = params.getStr("targetDataSourceId");
        targetTableName = params.getStr("targetTableName");
        originSrid = params.getStr("originSrid");
        targetSrid = params.getStr("targetSrid");
        spatialField = params.getStr("spatialField");
        mode = params.getStr("mode");

        PipelineBean pipeline = new PipelineBean();
        pipeline.setResultFile(System.getProperty("user.dir") + File.separator + "result_file");
        DatasetBean dataSet = new DatasetBean();
        dataSet.setDataSourceId(originDataSourceId);
        dataSet.setTableName(originTableName);
        pipeline.setDataSet(dataSet);

        List<OperatorBean> ops = new LinkedList<>();
        ops.add(buildReProj());
        ops.add(buildPgSink());

        pipeline.setOperators(ops);
        IPipelineOperator iPipelineOperator = this.client.pipelineOperator();
        BaseResponse response = iPipelineOperator.startPipeline(pipeline);
        iPipelineOperator.onStart(response.getRequestId(), () -> {
            this.log("重投影开始");
        });
        iPipelineOperator.onSuccess(response.getRequestId(), () -> {
            this.log("重投影成功");
            String log = iPipelineOperator.log(response.getRequestId());
            this.log(log);
            this.successExit();
        });
        iPipelineOperator.onError(response.getRequestId(), () -> {
            this.error("重投影失败");
            String log = iPipelineOperator.log(response.getRequestId());
            this.error(log);
            this.failedExit();
        });

        this.waiting(24);
    }

    public OperatorBean buildReProj() {
        OperatorBean operatorBean = new OperatorBean();
        operatorBean.setClassName("com.northpool.stpprocess.operator.spatial.vector.ReProjOperator");

        List<ParamBean> params = new LinkedList<>();
        params.add(new ParamBean("spatialField", this.spatialField));
        params.add(new ParamBean("sourceSrid", this.originSrid));
        params.add(new ParamBean("targetSrid", this.targetSrid));
        operatorBean.setStartParam(params);
        return operatorBean;
    }

    public OperatorBean buildPgSink() {
        OperatorBean operatorBean = new OperatorBean();
        operatorBean.setClassName("com.northpool.stpprocess.operator.basic.sink.PostgresSink");

        List<ParamBean> params = new LinkedList<>();
        params.add(new ParamBean("dataSourceId", targetDataSourceId));
        params.add(new ParamBean("tableName", targetTableName));
        params.add(new ParamBean("templateDataSourceId", originDataSourceId));
        params.add(new ParamBean("templateTableName", originTableName));
        operatorBean.setStartParam(params);

        return operatorBean;
    }
}
